

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:furaha_mkopo/api/fm_report_risk_api.dart';
import 'package:furaha_mkopo/commonTool/fm_language_tool.dart';
import 'package:furaha_mkopo/commonTool/fm_report_event_tool.dart';
import 'package:furaha_mkopo/commonTool/fm_time_tool.dart';
import 'package:furaha_mkopo/commonUI/fm_progress_hud.dart';
import 'package:furaha_mkopo/commonUI/fm_toast.dart';
import 'package:furaha_mkopo/net/fm_net_param_manager.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';

import 'fm_login_api.dart';
import 'fm_login_captcha_api.dart';
import 'fm_login_model.dart';

const int defaultSeconds = 60;

class FMLoginController extends GetxController with GetSingleTickerProviderStateMixin {

  TextEditingController phoneController = TextEditingController();

  TextEditingController codeController = TextEditingController();

  late AnimationController animationController;

  late Animation<double> animation;

  FocusNode focusNode = FocusNode();

  Timer? timer;

  int seconds = defaultSeconds;

  bool sendCodeBtn = false;

  bool isRadioSelected = true;

  BuildContext? context;

  int _shakeCount = 0;
  final int _maxShakes = 2;

  int startTime = 0;

  Position? position;

  @override
  void onInit() {
    animationController = AnimationController(
      duration: const Duration(milliseconds: 100), // 每次抖动持续时间
      vsync: this,
    );

    animation = Tween<double>(begin: 0.0, end: 10.0).animate(animationController)
      ..addListener(() {
        update(["updateAnimation"]);
      });

    animationController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        animationController.reverse(); // 动画结束后反向执行
      } else if (status == AnimationStatus.dismissed) {

        if (_shakeCount >= _maxShakes) {
          return;
        }else{
          _shakeCount++;
        }

        animationController.forward(); // 继续前进，形成重复抖动
      }
    });
  }

  @override
  void onClose() {
    phoneController.dispose();
    codeController.dispose();
    focusNode.dispose();
    animationController.dispose();
    super.onClose();
  }

  void onPhoneChanged(String phone) {

  }

  void onCodeChanged(String code) {

  }
  
  void sendCode() {
    if (phoneController.text.isEmpty) {
      FMToast.showText("Please enter your phone number");
      return;
    }

    if (seconds != defaultSeconds) {
      return;
    }

    startTime = FMTimeTool.currentTime;

    FMLoginCaptchaApi api = FMLoginCaptchaApi(
      phone: phoneController.text
    );

    FMProgressHud.showLoading();
    api.send().then((value){
      FMProgressHud.hideLoading();
      if (value.code == 0) {
          startTimer();

          FocusScope.of(context!).requestFocus(focusNode);
          FMToast.showText(value.message ?? "Send Success");
      }else {
        FMToast.showText(value.message ?? "Network Connection Error");
      }
    });
  }

  void clickLogin() {
    if (phoneController.text.isEmpty) {
      FMToast.showText("Please enter your phone number");
      return;
    }

    if (codeController.text.isEmpty) {
      FMToast.showText("Please enter the verification code");
      return;
    }

    if (!isRadioSelected) {
      FMToast.showText("Please read and agree to the Privacy Policy");
      return;
    }

    FMProgressHud.showLoading();

    FMLoginApi api = FMLoginApi(
      phone: phoneController.text,
      code: codeController.text
    );

    api.send<FMLoginModel,FMLoginModel>(decodeType: FMLoginModel()).then((value){
      FMProgressHud.hideLoading();
      if (value.code == 0) {

        FMNetParamManager().setAbsence(value.data?.absence);

        reportRisk();

        Navigator.pop(context!);
      }else {
        FMToast.showText(value.message ?? "Network Connection Error");
        codeController.clear();
        _shakeCount = 0;
        animationController.forward();
      }
    });
  }

  void clickRadio() {
    isRadioSelected = !isRadioSelected;
    update(["updateRadio"]);
  }

  startTimer() {

    if (timer != null) {
      timer?.cancel();
    }

    Timer t = Timer.periodic(const Duration(milliseconds: 1000), (timer) {
      seconds --;
      if (seconds == 0) {
        timer.cancel();
        sendCodeBtn = true;
        seconds = defaultSeconds;
      }
      update(["updateTime"]);
    });
    timer = t;
  }

  bool codeEnable() {
    return sendCodeBtn && seconds == defaultSeconds;
  }

  String codeTitle() {
    if (seconds == defaultSeconds && !sendCodeBtn) {
      return FMLanguageTool.getText("Get Code");
    }else {
      return codeEnable() ? FMLanguageTool.getText("Retry") : "${FMLanguageTool.getText("Resend")}(${FMLanguageTool.getTimeText(seconds)})";
    }
  }

  void reportRisk() {
    int endTime = FMTimeTool.currentTime;

    FMReportEventTool.reportRisk("1", position?.latitude, position?.longitude, startTime, endTime);
  }
}